package org.xx.armory.spring5.security;

import org.springframework.stereotype.Component;
import org.xx.armory.spring5.jdbc.JdbcDao;
import org.xx.armory.spring5.jdbc.SqlAndArgsBuilder;

import java.util.Set;

import static java.sql.Types.VARCHAR;
import static org.xx.armory.commons.Validators.rejectIfBlank;

@Component
public class JdbcAuthenticationDao
        extends JdbcDao {
    /**
     * 通过用户名获取哈希后的密码。
     * <p>如果找不到指定用户名的用户，那么返回空字符串。</p>
     *
     * @param username
     *         用户名。
     * @return 哈希后的密码。
     * @throws IllegalArgumentException
     *         如果参数{@code username}是{@code null}或者只包含空白字符。
     */
    public String loadHashedPasswordByUsername(
            String username
    ) {
        return queryString(
                new SqlAndArgsBuilder()
                        .append("SELECT U_PWD FROM MY_USER WHERE U_ENABLED = 1 AND U_NAME = #username#")
                        .addArg("username", username, VARCHAR));
    }

    /**
     * 通过用户名获取授权集合。返回的集合不可被修改。
     * <p>如果找不到指定用户名的用户，那么返回空集合。</p>
     *
     * @param username
     *         用户名。
     * @return 授权集合。
     * @throws IllegalArgumentException
     *         如果参数{@code username}是{@code null}或者只包含空白字符。
     */
    public Set<String> loadAuthoritiesByUsername(
            String username
    ) {
        username = rejectIfBlank(username, "username").trim();

        return Set.copyOf(queryStringList(
                new SqlAndArgsBuilder()
                        .append("SELECT RP.PERM_ID FROM MY_ROLE_PERM RP")
                        .append("  INNER JOIN MY_USER_ROLE UR ON UR.R_NAME = RP.R_NAME")
                        .append("  INNER JOIN MY_ROLE R ON R.R_NAME = UR.R_NAME AND R.R_ENABLED = 1")
                        .append("  INNER JOIN MY_USER U ON U.U_NAME = UR.U_NAME AND U.U_ENABLED = 1")
                        .append("WHERE U.U_NAME = #username#")
                        .addArg("username", username, VARCHAR)
        ));
    }
}
